package bishiqiangxun;
import java.util.*;
public class Test3 {
    //题目 : day30 第三题  最长公共子序列
    //算法 : 动态递归  线性dp
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        //动态规划  线性dp
        //可以定义一个数组找 两个字符串 的最长公共子序列
        //输入
        int n = in.nextInt();
        int m = in.nextInt();
        char[] cs1 = in.next().toCharArray();
        char[] cs2 = in.next().toCharArray();
        //状态转移方程
        //分两种情况  一种是i 和 j下标对应的元素相同 还有一种是不同
        int[][] dp = new int[n+1][m+1];  //多加一行
        for(int i = 1;i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(cs1[i-1] == cs2[j-1]) {
                    dp[i][j] = dp[i-1][j-1] + 1; //相同了直接找两个字符串在0~i-1  j-1  范围内的最长公共子序列 刚好是dp[i-1][j-1]
                }else
                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
            }
        }
        System.out.println(dp[n][m]);
    }
}
